<script setup>
import { reactive, toRefs, ref, onMounted } from 'vue';
import {
  ElCascader,
  ElCheckbox,
  ElCheckboxGroup,
  ElDialog,
  ElEmpty,
  ElForm,
  ElFormItem,
  ElInput,
  ElOption,
  ElSelect,
  ElTag,
} from 'element-plus';
import { OPERATION_TYPE } from '@/common/common-const';
import { isMobile } from '@/common/common-helper';
import { useSystemStore } from '@/stores';

const props = defineProps({
  userData: {
    type: Object,
  },
  userType: {
    type: String,
  },
  userShow: {
    type: Boolean,
  },
  checkedTreeItem: {
    type: Object,
  },
});
const { userShow, userType, userData, checkedTreeItem } = toRefs(props);
const emit = defineEmits(['handleUserShowEmit', 'handleUserParamEmit']);
const systemStore = useSystemStore();

const formRef = ref(null);
const treeData = ref([]);
const roleList = ref([]);
const roleChecked = ref([]);

const formInline = reactive({
  username: '',
  nickname: '',
  mobile: '',
  gender: null,
  deptId: '',
  remark: '',
  roleIds: [],
});

const rules = {
  username: [
    {
      required: true,
      message: '此项为必填项',
      trigger: 'blur',
    },
  ],
  nickname: [
    {
      required: true,
      message: '此项为必填项',
      trigger: 'blur',
    },
  ],
  gender: [
    {
      required: true,
      message: '此项为必填项',
      trigger: 'blur',
    },
  ],
  deptId: [
    {
      required: true,
      message: '此项为必填项',
      trigger: 'blur',
    },
  ],
  mobile: [
    {
      required: true,
      message: '此项为必填项',
      trigger: 'change',
    },
    {
      validator: (rule, value, callback) => {
        if (isMobile(value)) {
          callback();
        } else {
          callback(new Error('手机号码输入有误'));
        }
      },
      trigger: 'blur',
    },
  ],
};

const closeBoxShowDialog = () => {
  if (!formRef.value) return;
  formRef.value.resetFields();
  emit('handleUserShowEmit', false);
};

onMounted(() => {
  treeData.value = systemStore.systemDept;
  roleList.value = systemStore.systemRole;

  if (Object.keys(checkedTreeItem.value).length) {
    formInline.deptId = checkedTreeItem.value.id;
  } else {
    formInline.deptId = '';
  }

  if (userType.value == OPERATION_TYPE.ADD) {
    if (!formRef.value) return;
    formRef.value.resetFields();
    roleChecked.value = [];
  }

  if (Object.keys(userData.value).length) {
    formInline.username = userData.value.username;
    formInline.nickname = userData.value.nickname;
    formInline.mobile = userData.value.mobile;
    formInline.remark = userData.value.remark;
    formInline.deptId = userData.value.deptId;
    formInline.gender = userData.value.gender;

    formInline.roleIds = userData.value.roleList?.map((item) => {
      return item.id;
    });

    handleCheckedRoles();
  }
});

const handleChangeDept = (value) => {
  formInline.deptId = value[value.length - 1];
};

const handleCheckedRoles = () => {
  if (formInline.roleIds?.length) {
    roleChecked.value = roleList.value
      ?.map((item) => {
        if (formInline.roleIds?.includes(item?.id)) {
          return item.permissions;
        }
      })
      .filter((value) => value !== undefined)
      .reduce(function (a, b) {
        return a.concat(b);
      })
      .filter(function (item, index, self) {
        return self.findIndex((el) => el.id == item.id) === index;
      });
  } else {
    roleChecked.value = [];
  }
};

const handleSubmit = () => {
  formRef.value.validate((err) => {
    if (err) {
      if (userType.value == OPERATION_TYPE.ADD) {
        emit('handleUserParamEmit', formInline, OPERATION_TYPE.ADD);
      }

      if (userType.value == OPERATION_TYPE.EDIT) {
        formInline['id'] = userData.value.id;
        formInline.permissionIds = formInline.permissionIds?.length ? formInline.permissionIds : null;
        emit('handleUserParamEmit', formInline, OPERATION_TYPE.EDIT);
      }
    }
  });
};
</script>
<template>
  <div class="user-loading">
    <ElDialog
      v-if="userShow"
      v-model="userShow"
      align-center="center"
      :append-to-body="false"
      :title="userType == OPERATION_TYPE.EDIT ? '编辑' : userType == OPERATION_TYPE.ADD ? '新建' : '添加'"
      :close-on-click-modal="false"
      destroy-on-close
      draggable
      @close="closeBoxShowDialog()"
    >
      <main>
        <ElForm ref="formRef" :rules="rules" :model="formInline" label-position="top">
          <ElFormItem label="用户名" prop="username">
            <ElInput
              v-model.trim="formInline.username"
              show-word-limit
              maxlength="10"
              type="text"
              :disabled="userType == OPERATION_TYPE.EDIT"
            />
          </ElFormItem>
          <ElFormItem label="姓名" prop="nickname">
            <ElInput v-model.trim="formInline.nickname" show-word-limit maxlength="50" type="text" />
          </ElFormItem>
          <ElFormItem label="性别" prop="gender">
            <ElSelect v-model="formInline.gender" placeholder="请选择" style="width: 100%">
              <ElOption label="女" :value="1" />
              <ElOption label="男" :value="2" />
            </ElSelect>
          </ElFormItem>
          <ElFormItem label="手机号码" prop="mobile">
            <ElInput v-model.trim="formInline.mobile" show-word-limit maxlength="11" type="text" />
          </ElFormItem>
          <ElFormItem label="所属部门" prop="deptId">
            <ElCascader
              v-model="formInline.deptId"
              :options="treeData"
              :props="{
                checkStrictly: true,
                value: 'id',
                label: 'name',
              }"
              placeholder="请选择"
              style="width: 100%"
              @change="handleChangeDept"
            />
          </ElFormItem>
          <ElFormItem label="角色选择">
            <div class="border-box flex justify-between p-10px">
              <div class="border-left p-10px">
                <ElCheckboxGroup
                  v-if="roleList?.length"
                  v-model="formInline.roleIds"
                  class="flex flex-col"
                  @change="
                    () => {
                      handleCheckedRoles();
                    }
                  "
                >
                  <ElCheckbox v-for="item in roleList" :key="item.id" :label="item?.title" :value="item.id" />
                </ElCheckboxGroup>
                <ElEmpty v-if="!roleList?.length" description="暂无角色数据" />
              </div>
              <div class="border-right p-10px">
                <div v-if="roleChecked?.length">
                  <ElTag v-for="item in roleChecked" :key="item.id" size="large" type="warning" class="mb-5px mr-5px">{{
                    item?.title
                  }}</ElTag>
                </div>
                <ElEmpty v-if="!roleChecked?.length" description="暂无角色权限数据" />
              </div>
            </div>
          </ElFormItem>
          <ElFormItem label="角色描述">
            <ElInput v-model.trim="formInline.description" maxlength="50" type="text" />
          </ElFormItem>
        </ElForm>
      </main>
      <div class="dialog-footer">
        <div @click="closeBoxShowDialog()">取消</div>
        <div @click="handleSubmit()">保存</div>
      </div>
    </ElDialog>
  </div>
</template>

<style scoped lang="scss">
.user-loading {
  :deep(.el-dialog) {
    width: 700px;
    border-radius: 6px;
  }

  main {
    .border-box {
      width: 100%;
      min-height: 320px;
      max-height: 320px;

      .border-left,
      .border-right {
        width: 300px;
        min-height: 300px;
        max-height: 300px;

        overflow: auto;
        border: 1px solid $border-color;
        border-radius: 6px;
        &::-webkit-scrollbar {
          display: none;
          width: 0 !important;
        }
      }
    }
  }

  .dialog-footer {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    margin-top: 30px;
    text-align: right;
    div {
      display: flex;
      align-items: center;
      justify-content: center;
      width: 100px;
      height: 40px;
      font-size: 16px;
      border-radius: 4px;
      cursor: pointer;

      &:first-child {
        color: $base-color-info;
        background-color: $base-button-background-info;
      }

      &:nth-child(2) {
        margin: 0 20px;
        color: $base-button-color-green;
        background-color: $base-button-background-green;
      }
    }
  }
}
</style>
